import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable, throwError} from 'rxjs';
import {catchError, retry, tap} from 'rxjs/operators';
import {NzMessageService} from 'ng-zorro-antd';
import {StorageUtil} from '../../utils/storage.util';
import {HTTP_BASE_URL, JM_LOGIN_PATH} from '../../config/config';
import {StatusEnum} from '../enum/status.enum';
import {LoadingServer} from '../../common/loading/loading.server';
import {Router} from '@angular/router';


/**
 * @author leihfei
 * @date 2019-05-06
 * @description http拦截器，主要抓取系统请求过程以及错误提示
 */
@Injectable()
export class NoopIntereptor implements HttpInterceptor {
  constructor(
    private message: NzMessageService,
    private loading: LoadingServer,
    private router: Router) {
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    if (req.url !== 'assets/systemInfo.json') {
      req = req.clone({url: `${HTTP_BASE_URL}` + req.url});
    }
    // state?true（打开加载动画）：false（关闭加载动画）
    return next.handle(req).pipe(
      tap((event: any) => {
        // 取出body中的返回值
        if (event.body) {
          const status = event.body.status;
          if (status !== StatusEnum.SUCCESS) {
            // 出现了异常，如果是500,错误信息，405，警告信息
            if (status === StatusEnum.FAIL) {
              this.message.error(event.body.message);
            } else {
              if (status) {
                this.message.warning(event.body.message);
              }
            }
          }
          this.loading.hide();
        } else {
          // 出现预请求数据
        }
      }),
      retry(2),
      catchError((err) => this.handleError(err))
    );
  }

  /**
   * @author leihfei
   * @date 2019-04-03
   * @description 异常情况处理
   */
  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // 网络请求异常
      console.error('An error occurred:', error.error.message);
      this.message.error(error.error.message);
    } else {
      // 抛出的405,500等异常
      if (error.status === StatusEnum.NO_LOGIN_CODE) {
        // 您未登录
        this.message.warning(error.error.message);
        // this.router.navigate(['/login']);
        window.open(JM_LOGIN_PATH, '_self');
      }
      if (error.status === StatusEnum.FAIL) {
        // 直接返回500
        this.message.warning(error.error.message);
      }
      if (error.status === StatusEnum.AGAIN_TOKEN_CODE) {
        // 重新获取token
        const token = error.error.data;
        if (token) {
          StorageUtil.setLocalStorage('token', token);
          // 给出用户提示，访问异常，刷新重试
          this.message.warning('数据获取到票据，请刷新页面!');
        }
      }
      if (error.status === StatusEnum.NO_PRESSION_CODE) {
        // 您无权限访问，请联系管理员!
        this.message.warning(error.error.message);
      }
      if (error.status === StatusEnum.NO_SOURCES_CODE) {
        // 接口找不到
        this.message.warning('资源找不到，请联系管理员！');
      }
      if (error.status === StatusEnum.WARNING) {
        // 鉴权异常，请稍后重试!
        this.message.warning(error.error.message);
      }
      if (error.error.message === FrondEndErrorEnum.TOKENREALYFILTER) {
        this.message.error('后台服务未启动,请联系运维人员启动系统!');
      }
      if (error.error.message === FrondEndErrorEnum.GENERAL) {
        this.message.error('后台服务已掉线,请稍后重试!');
      }
      if (error.error.message === FrondEndErrorEnum.TIMESTAMP) {
        this.message.error('后台服务请求超时，请联系运维人员处理!');
      }
      if (error.error.message === FrondEndErrorEnum.SHORTCIRCUIT) {
        this.message.error('请不要恶意刷新，联系管理员启动系统!');
      }
      if (error.status === FrondEndErrorEnum.ZORRO) {
        this.message.error('网络不稳定，稍后再试!');
      }
      console.error(
        `返回状态码：  ${error.status}, ` +
        `返回内容: ${JSON.stringify(error.error)}`);
    }
    this.loading.hide();
    // 返回错误信息
    return throwError(
      '发生了请求异常');
  }

}

/**
 * @author leihfei
 * 后台服务报错，无法直接捕捉的异常枚举
 */
enum FrondEndErrorEnum {
  /**
   * 后台服务未启动
   */
  TOKENREALYFILTER = 'pre:TokenRelayFilter',
  /**
   * 后台服务掉线
   */
  GENERAL = 'GENERAL',

  /**
   * 后台服务请求超时
   */
  TIMESTAMP = 'Gateway Timeout',
  /**
   * 触发安全机制
   */
  SHORTCIRCUIT = 'SHORTCIRCUIT',
  /**
   * 返回了状态为0
   */
  ZORRO = 0
}
